﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;

namespace PhotoViewer
{
    public partial class frmPicAdjust : Form
    {
        public frmPicAdjust()
        {
            InitializeComponent();
        }

        //类字段声明
        public Image image;
        public string imageOldPath;

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            Graphics graphics = ptbNewPic.CreateGraphics();//将picNewBox作为graphic的画布

            saveFileDialog1.Filter = "BMP|*.bmp|JPEG|*.jpeg|GIF|*.gif|PNG|*.png";
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string picPath = saveFileDialog1.FileName;
                string picType = picPath.Substring(picPath.LastIndexOf(".") + 1, (picPath.Length - picPath.LastIndexOf(".") - 1));
                picType.ToLower();

                switch (picType)
                {
                    case "bmp":
                        Bitmap bt = new Bitmap(ptbNewPic.Image);//获取到改变后的图片
                        Bitmap mybmp = new Bitmap(bt, image.Width, image.Height);
                        mybmp.Save(picPath, ImageFormat.Bmp); //将图片保存在用户所选择的路径上
                        break;
                    case "jpeg":
                        Bitmap bt1 = new Bitmap(ptbNewPic.Image);
                        Bitmap mybmp1 = new Bitmap(bt1, ptbNewPic.Width, ptbNewPic.Height);//将图像大小设置为画布大小
                        mybmp1.Save(picPath, ImageFormat.Jpeg);
                        break;
                    case "gif":
                        Bitmap bt2 = new Bitmap(ptbNewPic.Image);
                        Bitmap mybmp2 = new Bitmap(bt2, ptbNewPic.Width, ptbNewPic.Height);
                        mybmp2.Save(picPath, ImageFormat.Gif);
                        break;
                    case "png":
                        Bitmap bt3 = new Bitmap(ptbNewPic.Image);
                        Bitmap mybmp3 = new Bitmap(bt3, ptbNewPic.Width, ptbNewPic.Height);
                        mybmp3.Save(picPath, ImageFormat.Png);
                        break;
                }
            }
        }

        /// <summary>
        /// 窗体加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmPicAdjust_Load(object sender, EventArgs e)
        {
            ptbOldPic.Image = image;
            ptbNewPic.Image = image;
        }

        /// <summary>
        /// 关闭窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure to close the window?", "Prompt", MessageBoxButtons.OKCancel, MessageBoxIcon.Information) == DialogResult.OK)
            {
                this.Close();
            }
        }

        #region 自定义方法
        /// <summary>
        /// 亮度调节
        /// </summary>
        /// <param name="image"></param>
        /// <param name="degree"></param>
        /// <returns></returns>
        public Bitmap AdjustLight(Bitmap bitmap, int degree)
        {
            if (bitmap == null)
            {
                return null;
            }
            if (degree < -255) degree = -255;   //degree最小值为-255
            if (degree > 255) degree = 255; //degree最大值只能为255

            try
            {
                int imageWidth = bitmap.Width;
                int imageHeight = bitmap.Height;
                int pixdegree = 0;   //用于存放每一个像素点每一位的值

                //BitmapData用于存放图像的一些属性，将指定的bitmap以24位图锁定在系统内存中
                BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

                unsafe //非安全代码
                {
                    byte* point = (byte*)data.Scan0;  //指向位图第一个像素的第一位（即RGB中的R）

                    //data.Stride是bitmap存在bitmapdata中的实际每行的字节数，而data.Width则是Image.width data.stride>=data.width*3;
                    //data.Stride是接近data.widht*3的4的整数倍
                    //（表示的是有多少个像素点，每个像素点由三个字节组成）
                    int offset = data.Stride - data.Width * 3; // offset为无用区域

                    for (int y = 0; y < data.Height; y++)//相当于一个二维矩阵有多少行
                    {
                        for (int x = 0; x < data.Width; x++)//每一行的像素点个数
                        {
                            //设置每一个像素点的每一位的值
                            //对像素点的每一位的值都增加degree(rgb范围在0-255之间)
                            for (int i = 0; i < 3; i++)
                            {
                                pixdegree = point[i] + degree;
                                //两个数相减有可能为负数，当为负数时取0，若不为负数则去想减得到的值
                                if (degree < 0) point[i] = (byte)Math.Min(0, pixdegree);
                                //两个正数相加有可能超过255，所以取二者之间的最小值
                                if (degree > 0) point[i] = (byte)Math.Max(255, pixdegree);
                            }//i

                            point += 3;//指向下一个像素点（每个像素点3个字节）
                        }//x

                        point += offset;//移到下一个扫描行
                    }//y
                }//unsafem

                bitmap.UnlockBits(data);//解除bitmap的内存锁定
                return bitmap;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 对比度
        /// </summary>
        /// <param name="bitmap"></param>
        /// <param name="degree"></param>
        /// <returns></returns>
        public Bitmap AdjustContrast(Bitmap bitmap, int degree)
        {

            if (bitmap == null)
            {
                return null;
            }

            if (degree < -100) degree = -100;
            if (degree > 100) degree = 100;


            double pixValue = 0;

            double contrast = (100.0 + degree) / 100.0;  //对比度算法
            contrast *= contrast;

            int width = bitmap.Width;
            int height = bitmap.Height;
            //获取到bitmap的属性
            BitmapData data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            unsafe
            {
                //指向位图第一个像素的第一位（即RGB中的R）
                byte* point = (byte*)data.Scan0;

                int offset = data.Stride - width * 3;//多余部分
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        // 处理指定位置像素的对比度
                        for (int i = 0; i < 3; i++)
                        {
                            //重新设置每一个像素点的值
                            pixValue = ((point[i] / 255.0 - 0.5) * contrast + 0.5) * 255;//对比度算法

                            if (pixValue < 0) pixValue = 0;
                            if (pixValue > 255) pixValue = 255;
                            point[i] = (byte)pixValue;
                        } // i
                        point += 3;
                    } // x
                    point += offset;
                } // y
            }//unsafe

            bitmap.UnlockBits(data);
            return bitmap;
        }

        #endregion

        #region TrackBar 的Scroll事件
        private void tbBright_Scroll(object sender, EventArgs e)
        {
            Bitmap oldBitmap = new Bitmap(ptbOldPic.Image);
            Bitmap image = AdjustLight(oldBitmap, tbBright.Value);
            this.ptbNewPic.Image = image;
        }

        private void tbContrast_Scroll(object sender, EventArgs e)
        {
            Bitmap oldBitmap = new Bitmap(ptbOldPic.Image);
            Bitmap image = AdjustContrast(oldBitmap, tbContrast.Value);
            this.ptbNewPic.Image = image;
        }
        #endregion

      

    }
}
